home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / alv.sun / alv.lha / src / convolve.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-08  |  5.2 KB  |  233 lines

  1. #include <stdio.h>
  2. #include "defs.h"
  3.  
  4. #define DEFAULT        0
  5. #define ENHANCED    1
  6. #define MANUAL        2
  7. #define SYMMETRIC    3
  8.  
  9. ypedef struct {
  10.     int   **image;
  11.     short   xsize, ysize;
  12.     int     nflag, spos, sneg;
  13. }       FILTER;
  14.  
  15. har   *progname;
  16. har   *filename;
  17. ixrect *pr1, *pr2;
  18. nt     scale_method;
  19. loat   scale;
  20. nt     offset;
  21. har   *filtername;
  22. hort   max_enhanced = -32768, min_enhanced = 32767;
  23. nt     mfx, mfy;
  24. nt     levels;
  25. FILTER *filter;
  26.  
  27. #ifdef STANDALONE
  28. ain(argc, argv, envp)
  29. #else
  30. onvolve_main(argc, argv, envp)
  31. #endif
  32.     int     argc;
  33.     char  **argv;
  34.     char  **envp;
  35. {
  36.     register int i, j;
  37.     FILTER *loadfilter();
  38.  
  39.     scale_method = DEFAULT;
  40.     scale = 1.;
  41.     offset = 0;
  42.     filtername = strsave("non-specified");
  43.     progname = strsave(argv[0]);
  44.     parse_profile(&argc, argv, envp);
  45.  
  46.     while ((gc = getopt(argc, argv, "sef:lm:M:")) != EOF)
  47.         switch (gc) {
  48.         case 's':
  49.             scale_method = SYMMETRIC;
  50.             break;
  51.         case 'e':
  52.             scale_method = ENHANCED;
  53.             break;
  54.         case 'f':
  55.             filtername = strsave(optarg);
  56.             break;
  57.         case 'l':
  58.             execlp("ls", "ls", "-C", FILTERS_DIR, 0);
  59.             exit();
  60.             break;
  61.         case 'm':
  62.             scale_method = MANUAL;
  63.             scale = atof(optarg);
  64.             break;
  65.         case 'M':
  66.             scale_method = MANUAL;
  67.             offset = (int) atof(optarg);
  68.             break;
  69.         case '?':
  70.             errflag++;
  71.             break;
  72.         }
  73.  
  74.     if (errflag)
  75.         error((char *) 0, "Usage: %s: [-e] [-s] [-f filter] [-l] [-m manual_scale] [-M manual_offset] [infile] [outfile]", progname);
  76.  
  77.     for (stream = 0; optind < argc; stream++, optind++)
  78.         if (stream < 2 && strcmp(argv[optind], "-") != 0)
  79.             if (freopen(argv[optind], mode[stream], f[stream]) == NULL)
  80.                 error("%s %s", PR_IO_ERR_INFILE, argv[optind]);
  81.  
  82.     filter = loadfilter(filtername);
  83.  
  84.     if ((pr1 = pr_load(stdin, NULL)) == NULL)
  85.         error(PR_IO_ERR_RASREAD);
  86.  
  87.     if (bitrestrict)
  88.         levels = calc_max(pr1)+1;
  89.     else
  90.         levels = MAXLEVEL(pr1->pr_depth);
  91.  
  92.     if ((pr2 = mem_create(pr1->pr_size.x, pr1->pr_size.y, pr1->pr_depth)) == NULL)
  93.         error("mem_create returned NULL");
  94.  
  95.     mfx = filter->xsize / 2;
  96.     mfy = filter->ysize / 2;
  97.  
  98.     switch (scale_method) {
  99.     case DEFAULT:
  100.         calc_default_scale();
  101.         one_pass();
  102.         break;
  103.     case ENHANCED:
  104.     case SYMMETRIC:
  105.         two_pass();
  106.         break;
  107.     case MANUAL:
  108.         one_pass();
  109.         break;
  110.     }
  111.  
  112.     pr_dump(pr2, stdout, NULL, RT_STANDARD, 0);
  113. }
  114.  
  115. FILTER *
  116. oadfilter(name)
  117.     char   *name;
  118. {
  119.     char    buf[BUFSIZ];
  120.     FILE   *fp;
  121.     char   *ep;
  122.     FILTER *filter;
  123.     int     xsize, ysize, ival;
  124.     register int i, j;
  125.     char   *getenv();
  126.  
  127.     if ((ep = getenv("FILTERS")) == NULL)
  128.         strcpy(buf, FILTERS_DIR);
  129.     else
  130.         strcpy(buf, ep);
  131.  
  132.     strcat(buf, "/");
  133.     strcat(buf, name);
  134.  
  135.     if (!(fp = fopen(buf, "r")))
  136.         error("Couldn't open filter %s", name);
  137.  
  138.     fscanf(fp, "%d %d", &xsize, &ysize);
  139.     filter = (FILTER *) malloc(sizeof(FILTER));
  140.     filter->image = (int **) dynamem(&(filter->image), sizeof(int), 2, ysize, xsize);
  141.  
  142.     filter->nflag = FALSE;
  143.     filter->xsize = xsize;
  144.     filter->ysize = ysize;
  145.  
  146.     for (j = 0; j < ysize; j++)
  147.         for (i = 0; i < xsize; i++) {
  148.             fscanf(fp, "%d", &ival);
  149.             filter->image[j][i] = ival;
  150.             if (ival < 0) {
  151.                 filter->nflag = TRUE;
  152.                 filter->sneg += ival;
  153.             } else
  154.                 filter->spos += ival;
  155.         }
  156.     filter->sneg = abs(filter->sneg);
  157.  
  158.     return filter;
  159. }
  160. alc_default_scale()
  161. {
  162.     if (filter->nflag) {
  163.         scale = (float) levels / (float) (MAX(filter->spos, filter->sneg) * 2);
  164.         offset = levels / 2;
  165.     } else {
  166.         scale = (float) levels / (float) (MAX(filter->spos, filter->sneg));
  167.         offset = 0;
  168.     }
  169. }
  170. ne_pass()
  171. {
  172.     register int total;
  173.     register int fj, fi;
  174.     register int i, j;
  175.  
  176.     warning("scale = %g on input, offset = %d on output", scale, offset);
  177.  
  178.     for (j = 0; j < pr1->pr_size.y - filter->ysize; j++)
  179.         for (i = 0; i < pr1->pr_size.x - filter->xsize; i++) {
  180.             total = 0;
  181.             for (fj = 0; fj < filter->ysize; fj++)
  182.                 for (fi = 0; fi < filter->xsize; fi++)
  183.                     total += (pr_get(pr1, i + fi, j + fj) * filter->image[fj][fi]);
  184.             pr_put(pr2, i + mfx, j + mfy, truncate((int) ((float) total * scale) + offset, levels, 0));
  185.         }
  186. }
  187. wo_pass()
  188. {
  189.     register int total;
  190.     register int least, most;
  191.     register int fj, fi;
  192.     register int i, j;
  193.     int     tmppix;
  194.     Pixrect *tmp;
  195.  
  196.     if ((tmp = mem_create(pr1->pr_size.x, pr1->pr_size.y, 32)) == NULL)
  197.         error("mem_create returned NULL");
  198.  
  199.     /* first pass */
  200.     least = 32768;
  201.     most -= 32767;
  202.     for (j = 0; j < pr1->pr_size.y - filter->ysize; j++)
  203.         for (i = 0; i < pr1->pr_size.x - filter->xsize; i++) {
  204.             total = 0;
  205.             for (fj = 0; fj < filter->ysize; fj++)
  206.                 for (fi = 0; fi < filter->xsize; fi++)
  207.                     total += (pr_get(pr1, i + fi, j + fj) * filter->image[fj][fi]);
  208.             pr_put(tmp, i + mfx, j + mfy, total);
  209.             least = MIN(total, least);
  210.             most = MAX(total, most);
  211.         }
  212.     least = abs(least);
  213.     
  214.     /* calculate scale and offset */
  215.     if (scale_method == SYMMETRIC) {
  216.         scale = (float) levels / (float) (MAX(least, most) * 2);
  217.         scale /= (filter->nflag) ? 2. : 1.;
  218.         offset = (filter->nflag) ? levels / 2 : 0;
  219.     } else {                /* enhanced */
  220.         scale = (float) levels / (float) (least + most);
  221.         offset = (filter->nflag) ? least * scale : 0;
  222.     }
  223.  
  224.     warning("scale = %g on filter, output offset = %d on output", scale, offset);
  225.  
  226.     /* second pass */
  227.     for (j = 0; j < pr1->pr_size.y - filter->ysize; j++)
  228.         for (i = 0; i < pr1->pr_size.x - filter->xsize; i++) {
  229.             tmppix = truncate((int) ((float) pr_get(tmp, i, j) * scale + offset), levels, 0);
  230.             pr_put(pr2, i, j, tmppix);
  231.         }
  232. }
  233.